// Give me the train sample, I will call the centroid of all label
// Input: file_name
// Output: centroid use the sparsity vector in "divide_info.config" which be used by my

#ifndef _CENTROID_CPP
#define _CENTROID_CPP

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

struct calc_centroid{

  typedef map<int,float> Ty_centroid;
  typedef map<float,Ty_centroid> Ty_labelc;
  typedef map<float,int> Ty_weight;

  string file_in,file_out;

  Ty_labelc label_centroid;
  Ty_weight label_weight;

  calc_centroid(string in,string out){
    file_in=in;
    file_out=out;

    label_centroid.clear();
    label_weight.clear();
  }

  void push_centroid(string rbuf){
    int i=0,pri=0;

    float label;

    int id;
    float v;

    while (rbuf[i]!=' ') i++; 
    label=atof(rbuf.substr(0,i).c_str());

    if (label_centroid.find(label)==label_centroid.end()){
      Ty_centroid tc;
      tc.clear();
      label_centroid[label]=tc;
      label_weight[label]=0;
    }

    Ty_labelc::iterator tlc_it=label_centroid.find(label);
    label_weight[label]++;
    
    while (rbuf[i]){
      pri=++i;
      while (rbuf[i]!=':') i++;
      id=atoi(rbuf.substr(pri,i-pri).c_str());
      
      pri=++i;
      while (rbuf[i] && rbuf[i]!=' ') i++;
      v=atof(rbuf.substr(pri,i-pri).c_str());

      if (tlc_it->second.find(id)==tlc_it->second.end())
	tlc_it->second[id]=v;
      else tlc_it->second[id]+=v;
    }
  }

  void outit(){
    Ty_labelc::iterator tlc_it;
    Ty_centroid::iterator tc_it;
    ofstream fout(file_out.c_str());
    for (tlc_it=label_centroid.begin();tlc_it!=label_centroid.end();tlc_it++){
      fout << tlc_it->first;
      int weight=label_weight[tlc_it->first];
      for (tc_it=tlc_it->second.begin();tc_it!=tlc_it->second.end();tc_it++){
	fout << " "
	     << tc_it->first << ":" << tc_it->second/weight;
      }
      fout << endl;
    }
    fout.close();
  }
  
  void calculate(){
    ifstream fin(file_in.c_str());
    string tmp;
    while (getline(fin,tmp)){
      push_centroid(tmp);	
    }
    fin.close();
  }

};

int main(int argc,char ** argv){

  if (argc!=2){
    cout << "parameter wrong";
    return 0;
  }

  calc_centroid cc(argv[1],"divide_info.config");
  cc.calculate();
  cc.outit();
}

#endif
